﻿using System;
using System.Collections.Generic;
//using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using LucasCode.PublicTypes;
//using Encoder = System.Drawing.Imaging.Encoder;
using System.Drawing.Imaging;
using System.Drawing;

namespace IoWorker
{
    public static class Compression
    {
        private const int ZIP_BLOCK_SIZE = 2048;
        private static readonly string[] CompressedContentExtensions = new[] { ".zip", ".jpg" };
        public static Stream GetUploadStream(UploadFile file)
        {
            string ext = Path.GetExtension(file.MatchFile.Filename).ToLower();
            foreach (string s in CompressedContentExtensions)
                if (s.Equals(ext))
                    return file.MatchFile.GetSource();
            return GetCompressedSource(file);
        }

        private static Stream GetCompressedSource(UploadFile file)
        {
            file.Status = IoHandler.IOStrings.Compressing;
            Stream s;
            string ext = Path.GetExtension(file.MatchFile.Filename).ToLower();
            switch (ext)
            {
                case ".bmp":
                    s = GetJpegStream(IoHandler.Properties.Settings.Default.JpegCompression, file);
                    break;
                default:
                    s = GetZipStream(file);
                    break;
            }
            s.Seek(0, SeekOrigin.Begin);
            return s;
        }

        private static Stream GetZipStream(UploadFile file)
        {
            var m = new MemoryStream();
            int zipbytes;
            long bytecount = 0, lastbytecount = 0, elapsed;// peek = 0;
            Byte[] zipbuffer = new Byte[ZIP_BLOCK_SIZE];
            
            using (Stream s = file.MatchFile.GetSource())
            {
                file.ResetTransferStats(s.Length);
                ZipOutputStream z = new ZipOutputStream(m);
                z.SetLevel(9);
                ZipEntry entry = new ZipEntry(Path.GetFileName(file.MatchFile.Filename));
                z.PutNextEntry(entry);

                while (!file.Aborted && ((zipbytes = s.Read(zipbuffer, 0, zipbuffer.Length)) > 0))
                {
                    z.Write(zipbuffer, 0, zipbytes);
                    file.TransferredBytesDelta(zipbytes);
                }
                file.ResetTransferStats();
                if (file.Aborted)
                    throw new UploadException(IoHandler.IOStrings.UploadAborted);
                z.Finish();
            }
            file.Progress = 100;
            return m;
        }

        private static Stream GetJpegStream(int Quality, UploadFile file)
        {
            var m = new MemoryStream();

            // Get an ImageCodecInfo object that represents the JPEG codec.
            ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");

            // Create an Encoder object based on the GUID

            // for the Quality parameter category.
            Encoder myEncoder = Encoder.Quality;

            // Create an EncoderParameters object.

            // An EncoderParameters object has an array of EncoderParameter

            // objects. In this case, there is only one

            // EncoderParameter object in the array.
            EncoderParameters myEncoderParameters = new EncoderParameters(1);

            // Save the bitmap as a JPEG file with quality level 25.
            EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, Quality);

            myEncoderParameters.Param[0] = myEncoderParameter;

            using (Stream s = file.MatchFile.GetSource())
                Image.FromStream(s).Save(m, myImageCodecInfo, myEncoderParameters);
            return m;
        }

        private static ImageCodecInfo GetEncoderInfo(String mimeType)
        {
            int j;
            ImageCodecInfo[] encoders;
            encoders = ImageCodecInfo.GetImageEncoders();
            for (j = 0; j < encoders.Length; ++j)
            {
                if (encoders[j].MimeType == mimeType)
                    return encoders[j];
            }
            return null;
        }
    }
}
